<script setup>
import * as Cesium from "cesium";
import { onMounted, ref } from "vue";

let viewer, baseLayer, enumLayer;
const tianditutkArr = [
  "590447cdbdf97775b57588a69ebb903d",
  "75f1cc913e8d68f7bd4b6f6383f78ceb",
  "4c4c0f03b0bdb58811f657fec0c09eb5",
];
// ['590447cdbdf97775b57588a69ebb903d', '75f1cc913e8d68f7bd4b6f6383f78ceb', '4c4c0f03b0bdb58811f657fec0c09eb5']
const tianditutk =
  tianditutkArr[Math.floor(Math.random() * tianditutkArr.length)];
Cesium.Ion.defaultAccessToken =
  "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJhZjE5ZTBhZC00YzE1LTQyMWYtOWM4MC00NmFlZjZhOGI3ZDciLCJpZCI6MTI4NTI2LCJpYXQiOjE2OTg4MzczOTN9.26EHXec7Ufty_B4e5_YWcB0t--zlquly7r66WVSS9wE";
// 设置Cesium默认视角
Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(
  108.4,
  21.3,
  129.3,
  48.6
);
// 在 Cesium 场景中模拟一个以震源为中心的同心椭圆波纹（地震波 / 水波扩散）效果
const addTsunami = () => {
  // 场景参数
  const origin = Cesium.Cartesian3.fromDegrees(120.0, 30.0, 0); // 震源位置
  const initialRadius = 10000.0; // 初始半径(米)
  const velocity = 500.0; // 传播速度(米/秒)
  const amplitude = 50.0; // 波浪振幅(米)
  const frequency = 0.1; // 波浪频率
  const maxLayers = 20; // 最大层数
  const maxRadius = 50000.0;     // 最大半径 (米) 超过后重新从初始值开始
  const waveCount = 5;  // 同时存在的波圈数量
  const color = Cesium.Color.fromBytes(0, 120, 255, 200); // 波纹主色

  // 创建波带容器
  const waveBands = [];

  // 生成初始波带
  for (let i = 0; i < maxLayers; i++) {
    const layer = createWaveBand(i);
    waveBands.push(layer);
  }
  console.log("waveBands", waveBands)
  // 创建单个波带
  function createWaveBand(layerIndex) {
    const semiMajorAxis = initialRadius * (layerIndex + 1);
    const semiMinorAxis = semiMajorAxis * 0.8; // 椭圆压缩比

    return viewer.entities.add({
      position: origin,
      ellipse: {
        semiMajorAxis: new Cesium.CallbackProperty((time) => updateRadius(time, layerIndex), false),
        semiMinorAxis: new Cesium.CallbackProperty((time) => updateRadius(time, layerIndex) * 0.8, false),
        material: new Cesium.CallbackProperty((time) => updateMaterial(time, layerIndex), false),
        outline: true,
        outlineColor: Cesium.Color.RED,
        outlineWidth: 2,
        // height: 0,
        height: new Cesium.CallbackProperty(updateHeight, false),
        fill: false
      }
    });
  }

  // 更新材质（透明度随半径衰减）
  function updateMaterial(time, index) {
    const radius = updateRadius(time, index);

    // 根据扩散进度计算透明度 (大半径越透明)
    const progress = (radius - initialRadius) / (maxRadius - initialRadius);
    const alpha = Math.max(0.0, 1.0 - progress);

    return new Cesium.ColorMaterialProperty(
      Cesium.Color.fromAlpha(color, alpha)
    );
  }

  // 更新半径函数
  function updateRadius(time, index) {
    const seconds = Cesium.JulianDate.secondsDifference(time, viewer.clock.startTime);

    // 每个波圈的起始时间相隔一段时间
    const delay = (index / waveCount) * 5.0; // 每个波圈延迟 5s
    const age = Math.max(0.0, seconds - delay);

    // 计算扩散半径
    const radius = initialRadius + velocity * age;
    if (radius > maxRadius) {
      return initialRadius; // 超过最大半径后重置
    }
    return radius;
  }

  // 更新高度函数
  function updateHeight(time, result) {
    const t = Cesium.JulianDate.secondsDifference(time, viewer.clock.currentTime);
    const height = amplitude * Math.sin(frequency * t + Math.PI / 2);
    return height;
  }

  // 时间动态更新
  viewer.clock.onTick.addEventListener(() => {
    waveBands.forEach((band, index) => {
      // 衰减透明度
      band.ellipse.material = new Cesium.ColorMaterialProperty(
        new Cesium.CallbackProperty(() => {
          const alpha = 1.0 / (1 + index * 0.05);
          return new Cesium.Color(0.0, 0.3, 0.8, alpha);
        }, false)
      );

      // 动态调整层数
      if (index > maxLayers - 5) {
        band.show = true;
      }
    });
  });

  // 设置相机视角
  viewer.camera.setView({
    destination: Cesium.Cartesian3.fromDegrees(120.5, 30.5, 1500000)
  });
}
onMounted(() => {
  baseLayer = new Cesium.ImageryLayer(
    new Cesium.WebMapTileServiceImageryProvider({
      url:
        "http://t0.tianditu.com/img_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=vec&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default&format=tiles&tk=" +
        tianditutk,
      layer: "tdtImgLayer",
      style: "default",
      format: "image/jpeg",
      tileMatrixSetID: "GoogleMapsCompatible", //使用谷歌的瓦片切片方式
      show: true,
    })
  );
  viewer = new Cesium.Viewer("cesiumContainer", {
    // animation: false, // 动画小组件
    baseLayerPicker: false, // 底图组件，选择三维数字地球的底图
    fullscreenButton: false, // 全屏组件
    vrButton: false, // VR模式
    geocoder: false, // 地理编码搜索组件
    homeButton: false, // 首页，点击之后将视图跳转到默认视角
    infoBox: false, // 信息框
    sceneModePicker: false, // 场景模式，切换2D、3D和Columbus Views（CV）模式
    selectionIndicator: false, // 是否显示选取指示器组件
    // timeline: false, // 时间轴
    navigationHelpButton: false, // 帮助提示，如何操作数字地球
    navigationInstructionsInitiallyVisible: false,
    // terrain: new Cesium.Terrain.fromWorldTerrain({
    //   url: Cesium.IonResource.fromAssetId(3956),
    //   requestWaterMask: true,    // 请求水体效果所需要的海水波浪数据
    //   requestVertexNormals: true   // 请求地形照明数据
    // }),
    baseLayer,
    contextOptions: {
      requestWebgl2: true, // 开启webgl2渲染
    },
  });

  enumLayer = new Cesium.ImageryLayer(
    new Cesium.WebMapTileServiceImageryProvider({
      url:
        "http://t0.tianditu.com/cia_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=cia&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default&format=tiles&tk=" +
        tianditutk,
      layer: "tdtCiaLayer",
      style: "default",
      format: "image/jpeg",
      tileMatrixSetID: "GoogleMapsCompatible", //使用谷歌的瓦片切片方式
      show: true,
    })
  );
  viewer.imageryLayers.add(enumLayer);
  window.baseLayer = baseLayer;
  window.viewer = viewer;
  window.enumLayer = enumLayer;
  addTsunami();
});
</script>

<template>
  <div id="cesiumContainer"></div>
</template>

<style lang="scss">
#cesiumContainer {
  width: 100vw;
  height: 100vh;
  position: relative;

  .cesium-viewer-bottom {
    visibility: hidden;
  }
}
</style>
